#include <iostream>

using namespace std;

const int N = 1e6 + 10;

int n; // 标记堆的大小
int heap[N];//小根堆

//向上调整算法
void up(int child)
{
	int parent = child / 2;

	while(parent >= 1 && heap[child] < heap[parent])
	{
		swap(heap[child], heap[parent]);
		child = parent;
		parent = child / 2;
	}
}

//向下调整算法
void down(int parent)
{
	int child = parent * 2; // 左孩子
	while(child <= n)
	{
		//找出两个孩子中的最小值
		if(child + 1 <= n && heap[child + 1] < heap[child]) child++;
		if(heap[child] >= heap[parent]) return;

		swap(heap[child], heap[parent]);
		parent = child;
		child = parent * 2;
	}
}

void push(int x)
{
	heap[++n] = x;
	up(n);
}

void pop()
{
	swap(heap[1], heap[n]);
	n--;
	down(1);
}

int main()
{
	int m; cin >> m;
	while(m--)
	{
		int op; cin >> op;
		if(op == 1)
		{
			int x; cin >> x;
			push(x);
		}
		else if(op == 2)
		{
			cout << heap[1] << endl;
		}
		else
		{
			pop();
		}
	}

	return 0;
}

